package com.golang.api.util;

import org.apache.commons.lang3.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;

public enum DateTimeFormatterEnum {

    /** yyyy-MM */
    YEAR_MONTH("yyyy-MM"),
    /** yyyyMM */
    SHORT_YEAR_MONTH("yyyyMM"),
    /** MM-dd */
    MONTH_DAY("MM-dd"),
    /** yyyy-MM-dd */
    DATE("yyyy-MM-dd"),
    /** yyyyMMdd */
    SHORT_DATE("yyyyMMdd"),
    /** yyyy-MM-dd HH:mm:ss */
    DATE_TIME("yyyy-MM-dd HH:mm:ss"),
    /** yyyyMMddHHmmss */
    SHORT_DATE_TIME("yyyyMMddHHmmss"),
    /** yyyy-MM-dd */
    TIME("HH-mm-ss"),
    /** yyyyMMdd */
    SHORT_TIME("HHmmss"),
    /** 通用 */
    UNIVERSAL_FORMATTER(new DateTimeFormatterBuilder().appendPattern("yyyy[-MM[-dd[ HH[:mm[:ss[.SSS]]]]]][-M[-dd[ HH[:mm[:ss[.SSS]]]]]]")
            .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
            .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
            .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
            .toFormatter());

    private String pattern;
    private DateTimeFormatter formatter;

    DateTimeFormatterEnum(String pattern){
        this.pattern = pattern;
        this.formatter = DateTimeFormatter.ofPattern(pattern);
    }

    DateTimeFormatterEnum(DateTimeFormatter dateTimeFormatter){
        this.formatter = dateTimeFormatter;
    }

    public static DateTimeFormatter getByPattern(String pattern){
        if(pattern == null) {
            return null;
        }
        for (DateTimeFormatterEnum pt : values()) {
            if(pattern.equals(pt.getPattern())) {
                return pt.formatter;
            }
        }
        return DateTimeFormatter.ofPattern(pattern);
    }

    public String getPattern() {
        return pattern;
    }

    public DateTimeFormatter getFormatter() {
        return formatter;
    }

    public String format(TemporalAccessor temporalAccessor) {
        if(temporalAccessor == null){
            return null;
        }
        return formatter.format(temporalAccessor);
    }

    public static LocalDateTime parseDateTime(String str){
        if(StringUtils.isBlank(str)){
            return null;
        }
        return LocalDateTime.parse(str, DATE_TIME.getFormatter());
    }

    public static LocalDate parseDate(String str){
        if(StringUtils.isBlank(str)){
            return null;
        }
        return LocalDate.parse(str, DATE.getFormatter());
    }

    public static LocalTime parseTime(String str){
        if(StringUtils.isBlank(str)){
            return null;
        }
        return LocalTime.parse(str, TIME.getFormatter());
    }

    public static LocalDateTime parse(String str){
        if(StringUtils.isBlank(str)){
            return null;
        }
        return LocalDateTime.parse(str, UNIVERSAL_FORMATTER.getFormatter());
    }

}
